package com.ruoyi.pcj.docking.websocket;

import com.alibaba.fastjson.JSON;
import com.mashuai.utils.base.MsAssertUtils;
import com.ruoyi.pcj.constant.TipConstant;
import com.ruoyi.pcj.docking.websocket.dto.ChatSendMsgDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 聊天的websocket服务
 *
 * @ClassName: WebSocketServer
 * @Author : mashuai
 * @Description: TODO
 */
@ServerEndpoint("/pcj/chat/{userId}")
@Component
@Slf4j
public class WebSocketChatServer {

    //存放当前在线用户信息会话
    private static Map<Long, Session> userSessionsMap = new ConcurrentHashMap<>();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") Long userId) {
        MsAssertUtils.objIsNull(userId, TipConstant.LOGIN_FAIL);
        //判断是否已经存在链接
        if (userSessionsMap.containsKey(userId)) {
            userSessionsMap.remove(userId);
        } else {
            userSessionsMap.put(userId, session);
        }
        log.info("用户{}进入", userId);
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("userId") Long userId) {
        if (userSessionsMap.containsKey(userId)) {
            userSessionsMap.remove(userId);
            log.info("用户{} 退出", userId);
        }
    }

    /**
     * 收到客户端消息后调用的方法
     */
    @OnMessage
    public void onMessage(String message, @PathParam("userId") Long userId) {
        if (userId != null) {
            log.info("用户{} 发送消息:{}", userId, message);
            ChatSendMsgDto dto = JSON.parseObject(message, ChatSendMsgDto.class);
            //1v1聊
            if ("0".equals(dto.getChatType())) {
                sendToOne(dto, userId);
            }
            //群聊
            else if ("1".equals(dto.getChatType())) {
                sendToGroup(dto, userId);
            }
        }
    }

    /**
     * 发生错误时候
     */
    @OnError
    public void onError(Session session, Throwable error, @PathParam("userId") Long userId) {
        System.err.println();
    }


    /**
     * 指定发送消息
     ***/
    private void sendToOne(ChatSendMsgDto dto, Long userId) {
        Long toUserId = dto.getToUserId();
        //如果指定的用户，当前没在线，则不实时推送，把数据插入数据库
        if (userSessionsMap.containsKey(toUserId)) {
            Session session = userSessionsMap.get(toUserId);
            sendMsg(dto.getContent(), session);
            //todo 发送成功后 消息入库...
        }
    }

    /**
     * 群聊信息
     ***/
    private void sendToGroup(ChatSendMsgDto dto, Long userId) {
        String groupId = dto.getGroupId();
        if (groupId != null) {
            //todo 获取该群组的所有用户id，然后从userSessionsMap中获取已在线的用户，进行推送
        }
    }


    /**
     * 发送信息
     **/
    private void sendMsg(String content, Session session) {
        try {
            session.getBasicRemote().sendText(content);
            //todo 发送成功后 消息入库
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
